import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 批量重命名哔哩哔哩缓存文件的视频名字,将音视频转换为mp4格式
 * 适用于哔哩哔哩缓存为video.m4s和audio.m4s两个分开的文件时使用
 * 只需修改文件夹所在目录即可
 */

public class FFMpegChangeVideo {

    private String ffmpegEXE;
    //视频原地址的基础位置
    private static String baseVideoInputPath = "/Users/suxiaomeng/Desktop/download/96028486";
    //格式转换后视频放置位置
    private static String videoOutputPath = "/Users/suxiaomeng/Study/视频";

    public FFMpegChangeVideo(String ffmpegEXE) {
        super();
        this.ffmpegEXE = ffmpegEXE;
    }

    public static void main(String[] args) {

        File file = new File(baseVideoInputPath);        //获取其file对象
        func(file);

    }

    //拼接ffmpeg的执行参数
    public void convertor(String videoInputPath, String videoOutputPath, String videoOutputName) throws Exception {
        //执行参数形如：
        //ffmpeg -i input.mp4 -y output.avi
        //ffmpeg -i video.m4s -i audio.m4s -codec copy 0.mp4
        List<String> command = new ArrayList();
        command.add(ffmpegEXE);

        command.add("-i");
        command.add(videoInputPath + "/video.m4s");
        command.add("-i");
        command.add(videoInputPath + "/audio.m4s");
        //一个参数一个add,不可连写如：command.add("-codec copy");程序无法识别，会报错
        command.add("-codec");
        command.add("copy");
        command.add(videoOutputPath + "/" + videoOutputName + ".mp4");

        MediaUtil.executeCommand(command);
    }

    //拼接ffmpeg的执行参数
    public void convertor2(String filelistPath,String videoOutputPath, String videoOutputName) throws Exception {
        //执行参数形如：

        //ffmpeg -f concat -i filelist.txt -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4

        List<String> command = new ArrayList();
        //一个参数一个add,不可连写如：command.add("-codec copy");程序无法识别，会报错
        command.add(ffmpegEXE);
        command.add("-f");
        command.add("concat");
        command.add("-i");
        command.add(filelistPath);
        command.add("-acodec");
        command.add("copy");
        command.add("-vcodec");
        command.add("copy");
        command.add("-absf");
        command.add("aac_adtstoasc");
        command.add(videoOutputPath + "/" + videoOutputName + ".mp4");

        MediaUtil.executeCommand(command);
    }

    private static void func(File file) {

        File[] fs = file.listFiles();
        //配置ffmpeg路径
        FFMpegChangeVideo ffmpeg = new FFMpegChangeVideo("/usr/local/Cellar/ffmpeg/4.2.2/bin/ffmpeg");

        for (File f : fs) {
            if (f.isDirectory())    //若是目录，则递归打印该目录下的文件
            {
                func(f);
            }
            if (f.getName().contains("entry.json")) {
                //1、读取entry.json配置文件
                String content = "";
                try {
                    content = FileUtils.readFileToString(f, "UTF-8");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //获取原文件路径
                String oldPath = f.getPath().replace("entry.json", "");

                //获取课程名称
                String title = JSON.parseObject(content).getString("title");
                // String newPath = "/Users/suxiaomeng/Study/视频/黑马Java基础+就业班+各种项目idea版本";//视频放的新地址

                //读取视频缓存目录文件夹名称
                String videoPath = JSON.parseObject(content).getString("type_tag");

                //判断是否存在该文件夹，不存在则新建
                isChartPathExist(videoOutputPath + "/" + title);

                //获取父文件夹名称，用于序列号命名
                String parent = f.getParentFile().getName();

                //获取当前视频的序号
                String no = JSON.parseObject(content).getJSONObject("page_data").getString("page");

                //读取json文件中该段视频段名称
                String newFileName = JSON.parseObject(content).getJSONObject("page_data").getString("part");
                //String newFileName = parent+"-"+JSON.parseObject(content).getJSONObject("page_data").getString("part") + ".blv";

                if (Integer.valueOf(no) < 10) {
                    newFileName = "0" + no + "-" + newFileName;
                } else {
                    newFileName = no + "-" + newFileName;
                }

                String videoInputPath = oldPath + videoPath;

                System.out.println("FFMpegTest.func.原视频地址=" + videoInputPath);
                System.out.println("FFMpegTest.func.新地址=" + (videoOutputPath+"/"+title));
                System.out.println("FFMpegTest.func.合并后的名称=" + newFileName);
                try {
                    ffmpeg.convertor(videoInputPath,(videoOutputPath+"/"+title),newFileName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读取json文件
    public static String readJsonFile(String fileName) {
        String jsonStr = "";
        try {
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    //dirPath 文件夹磁盘路径 
    private static void isChartPathExist(String dirPath) {

        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        } else {
            System.out.println(dirPath + " 该文件夹已经存在！");
        }
    }

}